home *** CD-ROM | disk | FTP | other *** search
/ Aminet 16 / Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso / Aminet / comm / term / term_source.lha / Extras / Source / term-source.lha / PickFile.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  12KB  |  643 lines

  1. /*
  2. **    PickFile.c
  3. **
  4. **    Simplified file selection routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16. enum    {    GAD_LIST=1,GAD_USE,GAD_SELECT,GAD_CANCEL };
  17.  
  18. BOOL
  19. ValidateFile(STRPTR FileName,LONG Type,STRPTR RealName)
  20. {
  21.     BPTR Segment;
  22.     BOOL Valid;
  23.  
  24.     Valid = FALSE;
  25.  
  26.     if(Segment = LoadSeg(FileName))
  27.     {
  28.         ULONG *SegmentData;
  29.         UWORD *Match;
  30.         BPTR SegPtr;
  31.         BOOL GotIt;
  32.         LONG Size;
  33.  
  34.         SegPtr = Segment;
  35.         GotIt = FALSE;
  36.  
  37.         do
  38.         {
  39.             SegmentData = (ULONG *)BADDR(SegPtr);
  40.  
  41.             SegPtr    = (BPTR)SegmentData[0];
  42.             Size    = SegmentData[-1] - 2 * sizeof(ULONG) - sizeof(struct Resident);
  43.             Match    = (UWORD *)(SegmentData + 1);
  44.  
  45.             while(!GotIt && Size > 0)
  46.             {
  47.                 if(*Match == RTC_MATCHWORD)
  48.                 {
  49.                     struct Resident *Resident = (struct Resident *)Match;
  50.  
  51.                     if(Resident->rt_MatchTag == Resident)
  52.                     {
  53.                         if(Resident->rt_Type == Type && Resident->rt_Name)
  54.                         {
  55.                             if(!Stricmp(FilePart(FileName),Resident->rt_Name))
  56.                             {
  57.                                 if(RealName)
  58.                                     strcpy(RealName,Resident->rt_Name);
  59.  
  60.                                 Valid = TRUE;
  61.                             }
  62.                         }
  63.  
  64.                         GotIt = TRUE;
  65.                     }
  66.                 }
  67.  
  68.                 Match    += 2;
  69.                 Size    -= sizeof(ULONG);
  70.             }
  71.         }
  72.         while(!GotIt && SegPtr);
  73.  
  74.         UnLoadSeg(Segment);
  75.     }
  76.  
  77.     return(Valid);
  78. }
  79.  
  80.     /* AddFile(struct List *List,STRPTR Name):
  81.      *
  82.      *    Add another file to the list:
  83.      */
  84.  
  85. STATIC VOID
  86. AddFile(struct List *List,STRPTR Name)
  87. {
  88.     struct Node *NewNode;
  89.  
  90.     if(NewNode = CreateNode(Name))
  91.     {
  92.         struct Node *Node;
  93.         LONG Result;
  94.  
  95.         for(Node = List->lh_Head ; Node->ln_Succ ; Node = Node->ln_Succ)
  96.         {
  97.             Result = Stricmp(Name,Node->ln_Name);
  98.  
  99.             if(Result < 0)
  100.             {
  101.                 Insert(List,NewNode,Node->ln_Pred);
  102.                 return;
  103.             }
  104.  
  105.             if(Result == 0)
  106.             {
  107.                 FreeVecPooled(NewNode);
  108.                 return;
  109.             }
  110.         }
  111.  
  112.         AddTail(List,NewNode);
  113.     }
  114. }
  115.  
  116.     /* FileMultiScan(struct List *FileList,STRPTR Directory,STRPTR Pattern):
  117.      *
  118.      *    Scan an assignment, also handles multipath assignments.
  119.      */
  120.  
  121. STATIC VOID
  122. FileMultiScan(struct List *FileList,STRPTR Directory,STRPTR Pattern,LONG Type)
  123. {
  124.     UBYTE MatchBuffer[MAX_FILENAME_LENGTH];
  125.     struct MsgPort *FileSysTask;
  126.     struct DevProc *DevProc;
  127.     D_S(struct FileInfoBlock,FileInfo);
  128.  
  129.     DevProc        = NULL;
  130.     FileSysTask    = GetFileSysTask();
  131.  
  132.     if(ParsePatternNoCase(Pattern,MatchBuffer,sizeof(MatchBuffer)) != -1)
  133.     {
  134.             /* Loop until all assignments are
  135.              * processed.
  136.              */
  137.  
  138.         do
  139.         {
  140.                 /* Get the default filesystem task
  141.                  * in case we stumble upon NULL
  142.                  * directory locks.
  143.                  */
  144.  
  145.             if(DevProc = GetDeviceProc(Directory,DevProc))
  146.             {
  147.                     /* Set the default filesystem task. */
  148.  
  149.                 SetFileSysTask(DevProc->dvp_Port);
  150.  
  151.                     /* Check the object type. */
  152.  
  153.                 if(Examine(DevProc->dvp_Lock,FileInfo))
  154.                 {
  155.                         /* Is it really a directory? */
  156.  
  157.                     if(FileInfo->fib_DirEntryType > 0)
  158.                     {
  159.                             /* Scan the directory... */
  160.  
  161.                         while(ExNext(DevProc->dvp_Lock,FileInfo))
  162.                         {
  163.                                 /* Did we find a file? */
  164.  
  165.                             if(FileInfo->fib_DirEntryType < 0)
  166.                             {
  167.                                     /* Does the name match the template? */
  168.  
  169.                                 if(MatchPatternNoCase(MatchBuffer,FileInfo->fib_FileName))
  170.                                 {
  171.                                     if(Type == -1)
  172.                                         AddFile(FileList,FileInfo->fib_FileName);
  173.                                     else
  174.                                     {
  175.                                         UBYTE LocalBuffer[MAX_FILENAME_LENGTH],RealName[MAX_FILENAME_LENGTH];
  176.  
  177.                                         strcpy(LocalBuffer,Directory);
  178.  
  179.                                         if(AddPart(LocalBuffer,FileInfo->fib_FileName,sizeof(LocalBuffer)))
  180.                                         {
  181.                                             if(ValidateFile(LocalBuffer,Type,RealName))
  182.                                                 AddFile(FileList,RealName);
  183.                                         }
  184.                                     }
  185.                                 }
  186.                             }
  187.                         }
  188.                     }
  189.                 }
  190.             }
  191.             else
  192.                 break;
  193.         }
  194.         while(DevProc && (DevProc->dvp_Flags & DVPF_ASSIGN));
  195.     }
  196.  
  197.         /* Reset the default filesystem task. */
  198.  
  199.     SetFileSysTask(FileSysTask);
  200.  
  201.         /* Free device process data. */
  202.  
  203.     if(DevProc)
  204.         FreeDeviceProc(DevProc);
  205. }
  206.  
  207.     /* BuildFileList(STRPTR Directory,STRPTR Pattern):
  208.      *
  209.      *    Build a list of files in an assigned directory
  210.      *    matching a certain pattern.
  211.      */
  212.  
  213. STATIC struct List *
  214. BuildFileList(STRPTR Directory,STRPTR Pattern,LONG Type)
  215. {
  216.     struct List    *FileList;
  217.     APTR OldPtr;
  218.     BPTR NewDir;
  219.  
  220.     FileList = NULL;
  221.  
  222.         /* No DOS requesters, please! */
  223.  
  224.     DisableDOSRequesters(&OldPtr);
  225.  
  226.         /* Is the assignment present? */
  227.  
  228.     if(NewDir = Lock(Directory,ACCESS_READ))
  229.     {
  230.             /* Allocate space for the new list. */
  231.  
  232.         if(FileList = CreateList())
  233.         {
  234.                 /* Will we have to deal with
  235.                  * an assignment or a volume?
  236.                  */
  237.  
  238.             if(IsAssign(Directory))
  239.                 FileMultiScan(FileList,Directory,Pattern,Type);
  240.             else
  241.             {
  242.                 UBYTE MatchBuffer[MAX_FILENAME_LENGTH];
  243.                 D_S(struct FileInfoBlock,FileInfo);
  244.  
  245.                 if(ParsePatternNoCase(Pattern,MatchBuffer,sizeof(MatchBuffer)) != -1)
  246.                 {
  247.                         /* Take a look at the assignment. */
  248.  
  249.                     if(Examine(NewDir,FileInfo))
  250.                     {
  251.                             /* Does it really refer to a directory? */
  252.  
  253.                         if(FileInfo->fib_DirEntryType > 0)
  254.                         {
  255.                                 /* Examine the whole directory. */
  256.  
  257.                             while(ExNext(NewDir,FileInfo))
  258.                             {
  259.                                     /* Is it a file? */
  260.  
  261.                                 if(FileInfo->fib_DirEntryType < 0)
  262.                                 {
  263.                                     if(MatchPatternNoCase(MatchBuffer,FileInfo->fib_FileName))
  264.                                     {
  265.                                         if(Type == -1)
  266.                                             AddFile(FileList,FileInfo->fib_FileName);
  267.                                         else
  268.                                         {
  269.                                             UBYTE LocalBuffer[MAX_FILENAME_LENGTH],RealName[MAX_FILENAME_LENGTH];
  270.  
  271.                                             strcpy(LocalBuffer,Directory);
  272.  
  273.                                             if(AddPart(LocalBuffer,FileInfo->fib_FileName,sizeof(LocalBuffer)))
  274.                                             {
  275.                                                 if(ValidateFile(LocalBuffer,Type,RealName))
  276.                                                     AddFile(FileList,RealName);
  277.                                             }
  278.                                         }
  279.                                     }
  280.                                 }
  281.                             }
  282.                         }
  283.                     }
  284.                 }
  285.             }
  286.  
  287.             if(Type == NT_DEVICE)
  288.             {
  289.                 UBYTE MatchBuffer[MAX_FILENAME_LENGTH];
  290.  
  291.                 if(ParsePatternNoCase(Pattern,MatchBuffer,sizeof(MatchBuffer)) != -1)
  292.                 {
  293.                     struct Node *Node;
  294.  
  295.                     Forbid();
  296.  
  297.                     for(Node = SysBase->DeviceList.lh_Head ; Node->ln_Succ ; Node = Node->ln_Succ)
  298.                     {
  299.                         if(MatchPatternNoCase(MatchBuffer,Node->ln_Name))
  300.                             AddFile(FileList,Node->ln_Name);
  301.                     }
  302.  
  303.                     Permit();
  304.                 }
  305.             }
  306.  
  307.             if(Type == NT_LIBRARY)
  308.             {
  309.                 UBYTE MatchBuffer[MAX_FILENAME_LENGTH];
  310.  
  311.                 if(ParsePatternNoCase(Pattern,MatchBuffer,sizeof(MatchBuffer)) != -1)
  312.                 {
  313.                     struct Node *Node;
  314.  
  315.                     Forbid();
  316.  
  317.                     for(Node = SysBase->LibList.lh_Head ; Node->ln_Succ ; Node = Node->ln_Succ)
  318.                     {
  319.                         if(MatchPatternNoCase(MatchBuffer,Node->ln_Name))
  320.                             AddFile(FileList,Node->ln_Name);
  321.                     }
  322.  
  323.                     Permit();
  324.                 }
  325.             }
  326.  
  327.                 /* Does the list contain any entries? */
  328.  
  329.             if(IsListEmpty(FileList))
  330.             {
  331.                 FreeVecPooled(FileList);
  332.  
  333.                 FileList = NULL;
  334.             }
  335.         }
  336.  
  337.             /* Release the lock on the directory. */
  338.  
  339.         UnLock(NewDir);
  340.     }
  341.  
  342.         /* Enable DOS requesters again. */
  343.  
  344.     EnableDOSRequesters(OldPtr);
  345.  
  346.         /* Return the file name list. */
  347.  
  348.     return(FileList);
  349. }
  350.  
  351.     /* PickFile(STRPTR Directory,STRPTR Pattern,STRPTR Prompt,STRPTR Name):
  352.      *
  353.      *    Your nice file selection routine. No need to hunt for
  354.      *    a library/device by checking all assignments by hand.
  355.      */
  356.  
  357. BOOL
  358. PickFile(struct Window *Window,STRPTR Directory,STRPTR Pattern,STRPTR Prompt,STRPTR Name,LONG Type)
  359. {
  360.     UBYTE DummyBuffer[MAX_FILENAME_LENGTH];
  361.     struct FileRequester *FileRequest;
  362.     struct List *FileList;
  363.     BOOL Result;
  364.  
  365.     Result = FALSE;
  366.  
  367.     if(FileList = BuildFileList(Directory,Pattern,Type))
  368.     {
  369.         struct LayoutHandle *Handle;
  370.  
  371.         if(Handle = LT_CreateHandleTags(Window->WScreen,
  372.             LAHN_LocaleHook,    &LocaleHook,
  373.         TAG_DONE))
  374.         {
  375.             struct Window *PanelWindow;
  376.             struct Node *Node;
  377.             ULONG Index,i;
  378.  
  379.             Index = (ULONG)~0;
  380.  
  381.             for(Node = FileList->lh_Head, i = 0 ; Node->ln_Succ ; Node = Node->ln_Succ, i++)
  382.             {
  383.                 if(!Stricmp(Node->ln_Name,Name))
  384.                 {
  385.                     Index = i;
  386.  
  387.                     break;
  388.                 }
  389.             }
  390.  
  391.             LT_New(Handle,
  392.                 LA_Type,    VERTICAL_KIND,
  393.             TAG_DONE);
  394.             {
  395.                 LT_New(Handle,
  396.                     LA_Type,    VERTICAL_KIND,
  397.                 TAG_DONE);
  398.                 {
  399.                     LONG MaxWidth,MaxHeight;
  400.  
  401.                     MaxWidth    = 0;
  402.                     MaxHeight    = 0;
  403.  
  404.                     if(FileList)
  405.                     {
  406.                         struct Node *Node;
  407.                         LONG Len;
  408.  
  409.                         for(Node = FileList->lh_Head ; Node->ln_Succ ; Node = Node->ln_Succ)
  410.                         {
  411.                             Len = strlen(Node->ln_Name);
  412.  
  413.                             if(Len > MaxWidth)
  414.                                 MaxWidth = Len;
  415.  
  416.                             MaxHeight++;
  417.                         }
  418.                     }
  419.  
  420.                     if(MaxWidth < 30)
  421.                         MaxWidth = 30;
  422.  
  423.                     if(MaxHeight < 10)
  424.                         MaxHeight = 10;
  425.                     else
  426.                     {
  427.                         if(MaxHeight > 20)
  428.                             MaxHeight = 20;
  429.                     }
  430.  
  431.                     LT_New(Handle,
  432.                         LA_Type,        LISTVIEW_KIND,
  433.                         LA_Chars,        30,
  434.                         LA_ID,            GAD_LIST,
  435.                         LALV_Lines,        10,
  436.                         LALV_MaxGrowX,    MaxWidth,
  437.                         LALV_MaxGrowY,    MaxHeight,
  438.                         LALV_ResizeY,    TRUE,
  439.                         GTLV_Labels,    FileList,
  440.                         GTLV_Selected,    Index,
  441.                         LALV_Link,        NIL_LINK,
  442.                         LALV_CursorKey,    TRUE,
  443.                     TAG_DONE);
  444.  
  445.                     LT_EndGroup(Handle);
  446.                 }
  447.  
  448.                 LT_New(Handle,
  449.                     LA_Type,VERTICAL_KIND,
  450.                 TAG_DONE);
  451.                 {
  452.                     LT_New(Handle,
  453.                         LA_Type,        XBAR_KIND,
  454.                         LAXB_FullSize,    TRUE,
  455.                     TAG_DONE);
  456.  
  457.                     LT_EndGroup(Handle);
  458.                 }
  459.  
  460.                 LT_New(Handle,LA_Type,HORIZONTAL_KIND,
  461.                     LAGR_SameSize,    TRUE,
  462.                     LAGR_Spread,    TRUE,
  463.                 TAG_DONE);
  464.                 {
  465.                     LT_New(Handle,
  466.                         LA_Type,        BUTTON_KIND,
  467.                         LA_LabelID,        MSG_GLOBAL_USE_GAD,
  468.                         LA_ID,            GAD_USE,
  469.                         LABT_ReturnKey,    TRUE,
  470.                         LABT_ExtraFat,    TRUE,
  471.                     TAG_DONE);
  472.  
  473.                     LT_New(Handle,
  474.                         LA_Type,        BUTTON_KIND,
  475.                         LA_LabelID,        MSG_TERMPICKFILE_SELECT_GAD,
  476.                         LA_ID,            GAD_SELECT,
  477.                         LABT_ExtraFat,    TRUE,
  478.                     TAG_DONE);
  479.  
  480.                     LT_New(Handle,
  481.                         LA_Type,        BUTTON_KIND,
  482.                         LA_LabelID,        MSG_GLOBAL_CANCEL_GAD,
  483.                         LA_ID,            GAD_CANCEL,
  484.                         LABT_EscKey,    TRUE,
  485.                         LABT_ExtraFat,    TRUE,
  486.                     TAG_DONE);
  487.  
  488.                     LT_EndGroup(Handle);
  489.                 }
  490.  
  491.                 LT_EndGroup(Handle);
  492.             }
  493.  
  494.             if(PanelWindow = LT_Build(Handle,
  495.                 LAWN_TitleText,        Prompt,
  496.                 LAWN_HelpHook,        &GuideHook,
  497.                 LAWN_Parent,        Window,
  498.                 WA_DepthGadget,        TRUE,
  499.                 WA_DragBar,            TRUE,
  500.                 WA_RMBTrap,            TRUE,
  501.                 WA_Activate,        TRUE,
  502.                 WA_SimpleRefresh,    TRUE,
  503.             TAG_DONE))
  504.             {
  505.                 struct IntuiMessage    *Message;
  506.                 struct Gadget *MsgGadget;
  507.                 ULONG MsgClass;
  508.                 UWORD MsgCode;
  509.                 BOOL Done;
  510.  
  511.                 LT_ShowWindow(Handle,TRUE);
  512.  
  513.                 PushWindow(PanelWindow);
  514.  
  515.                 Done = FALSE;
  516.  
  517.                 do
  518.                 {
  519.                     if(Wait(PORTMASK(PanelWindow->UserPort) | SIG_BREAK) & SIG_BREAK)
  520.                         break;
  521.  
  522.                     while(Message = (struct IntuiMessage *)LT_GetIMsg(Handle))
  523.                     {
  524.                         MsgClass    = Message->Class;
  525.                         MsgCode        = Message->Code;
  526.                         MsgGadget    = (struct Gadget *)Message->IAddress;
  527.  
  528.                         LT_ReplyIMsg(Message);
  529.  
  530.                         if(MsgClass == IDCMP_GADGETUP)
  531.                         {
  532.                             switch(MsgGadget->GadgetID)
  533.                             {
  534.                                 case GAD_USE:
  535.  
  536.                                     if(Index != (ULONG)~0)
  537.                                     {
  538.                                         struct Node *Node = GetListNode(Index,FileList);
  539.  
  540.                                         if(Node)
  541.                                         {
  542.                                             strcpy(Name,Node->ln_Name);
  543.  
  544.                                             Result = TRUE;
  545.                                         }
  546.                                     }
  547.  
  548.                                     Done = TRUE;
  549.                                     break;
  550.  
  551.                                 case GAD_CANCEL:
  552.  
  553.                                     Done = TRUE;
  554.                                     break;
  555.  
  556.                                 case GAD_LIST:
  557.  
  558.                                     Index = MsgCode;
  559.                                     break;
  560.  
  561.                                 case GAD_SELECT:
  562.  
  563.                                     strcpy(DummyBuffer,Name);
  564.  
  565.                                     if(FileRequest = OpenSingleFile(PanelWindow,Prompt,LocaleString(MSG_GLOBAL_SELECT_TXT),Pattern,DummyBuffer,sizeof(DummyBuffer)))
  566.                                     {
  567.                                         FreeAslRequest(FileRequest);
  568.  
  569.                                         strcpy(Name,DummyBuffer);
  570.  
  571.                                         if(Type != -1)
  572.                                         {
  573.                                             UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
  574.  
  575.                                             if(ValidateFile(DummyBuffer,Type,LocalBuffer))
  576.                                             {
  577.                                                 *PathPart(Name) = 0;
  578.  
  579.                                                 AddPart(Name,LocalBuffer,sizeof(LocalBuffer));
  580.                                             }
  581.                                         }
  582.  
  583.                                         Done = Result = TRUE;
  584.                                     }
  585.  
  586.                                     break;
  587.                             }
  588.                         }
  589.  
  590.                         if(MsgClass == IDCMP_IDCMPUPDATE)
  591.                         {
  592.                             struct Node *Node;
  593.  
  594.                             if(Node = GetListNode(Index = MsgCode,FileList))
  595.                             {
  596.                                 strcpy(Name,Node->ln_Name);
  597.  
  598.                                 Done = Result = TRUE;
  599.  
  600.                                 LT_PressButton(Handle,GAD_USE);
  601.                             }
  602.                         }
  603.                     }
  604.                 }
  605.                 while(!Done);
  606.  
  607.                 PopWindow();
  608.             }
  609.  
  610.             LT_DeleteHandle(Handle);
  611.         }
  612.  
  613.         DeleteList(FileList);
  614.     }
  615.     else
  616.     {
  617.         strcpy(DummyBuffer,Name);
  618.  
  619.         if(FileRequest = OpenSingleFile(Window,Prompt,LocaleString(MSG_GLOBAL_SELECT_TXT),Pattern,DummyBuffer,sizeof(DummyBuffer)))
  620.         {
  621.             FreeAslRequest(FileRequest);
  622.  
  623.             strcpy(Name,DummyBuffer);
  624.  
  625.             if(Type != -1)
  626.             {
  627.                 UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
  628.  
  629.                 if(ValidateFile(DummyBuffer,Type,LocalBuffer))
  630.                 {
  631.                     *PathPart(Name) = 0;
  632.  
  633.                     AddPart(Name,LocalBuffer,sizeof(LocalBuffer));
  634.                 }
  635.             }
  636.  
  637.             return(TRUE);
  638.         }
  639.     }
  640.  
  641.     return(Result);
  642. }
  643.